<template>
  <v-data-table
    :headers="headers"
    :items="userRolesData"
    hide-default-footer
    :disable-pagination="true"
    :loading="userRolesDataLoading"
    loading-text="正在加载数据中...请稍后"
    class="elevation-1"
  >
    <template v-slot:top>
      <v-toolbar flat>
        <v-toolbar-title>用户角色列表</v-toolbar-title>
        <v-divider class="mx-4" inset vertical />
        <v-spacer />
        <v-dialog
          v-model="dialog"
          max-width="500px"
        >
          <template v-slot:activator="{ on, attrs }">
            <v-btn
              color="primary"
              dark
              class="mb-2"
              v-bind="attrs"
              v-on="on"
            >
              添加用户角色
            </v-btn>
          </template>
          <v-card>
            <v-card-title>
              <span class="text-h5">{{ formTitle }}</span>
            </v-card-title>
            <v-card-text>
              <v-container>
                <v-text-field
                  v-model="editedItem.user_role_id"
                  label="用户角色ID"
                  readonly
                  disabled
                />
                <v-text-field
                  v-model="editedItem.user_role_title"
                  label="用户角色名称"
                  :rules="[rules.required]"
                />
              </v-container>
            </v-card-text>
            <v-card-actions>
              <v-spacer />
              <v-btn color="blue darken-1" text @click="close">取消</v-btn>
              <v-btn color="blue darken-1" text :loading="saveLoading" @click="save">保存</v-btn>
            </v-card-actions>
          </v-card>
        </v-dialog>
        <v-dialog v-model="dialogDelete" max-width="500px">
          <v-card>
            <v-card-title class="text-h5">你确定想要删除此项吗？</v-card-title>
            <v-card-actions>
              <v-spacer />
              <v-btn color="blue darken-1" text @click="closeDelete">取消</v-btn>
              <v-btn color="blue darken-1" text :loading="deleteLoading" @click="deleteItemConfirm">确定删除</v-btn>
              <v-spacer />
            </v-card-actions>
          </v-card>
        </v-dialog>
      </v-toolbar>
    </template>
    <template v-slot:item.default_user_role="{ item }">
      <v-switch
        v-model="item.default_user_role"
        inset
        :loading="item.defaultUserRoleLoading"
        @change="setDefaultUserRole(item)"
      />
    </template>
    <template v-slot:item.actions="{ item }">
      <v-icon
        class="mr-2"
        @click="editItem(item)"
      >
        mdi-pencil
      </v-icon>
      <v-icon
        @click="deleteItem(item)"
      >
        mdi-delete
      </v-icon>
    </template>
    <template v-slot:no-data>
      <v-btn
        color="primary"
        @click="initialize"
      >
        重新加载数据...
      </v-btn>
    </template>
  </v-data-table>
</template>

<script>
import { getOptions, setOptions } from '@/api/options'
import { deepClone } from '@/utils/index'

export default {
  name: 'SystemUserRole',
  data() {
    return {
      dialog: false,
      dialogDelete: false,
      headers: [
        { text: '角色ID', value: 'user_role_id' },
        { text: '角色名称', value: 'user_role_title' },
        { text: '默认角色', value: 'default_user_role' },
        { text: '操作名称', value: 'actions' }
      ],
      userRolesData: [],
      userRolesDataLoading: false,
      editedIndex: -1,
      editedItem: {
        user_role_id: this.createNewRoleId(),
        user_role_title: ''
      },
      defaultItem: {
        user_role_id: this.createNewRoleId(),
        user_role_title: ''
      },
      saveLoading: false,
      deleteLoading: false,
      rules: {
        required: value => !!value || '必填项，此项不能为空'
      },
      default_user_role: 0
    }
  },
  computed: {
    formTitle() {
      return this.editedIndex === -1 ? '添加用户角色' : '编辑用户角色'
    }
  },
  watch: {
    dialog(val) {
      val || this.close()
    },
    dialogDelete(val) {
      val || this.closeDelete()
    }
  },
  created() {
    this.initialize()
  },
  methods: {
    initialize() {
      this.userRolesDataLoading = true
      getOptions().then(response => {
        const userRolesData = response.data.user_roles || []
        this.default_user_role = response.data.default_user_role || 0
        this.userRolesData = userRolesData.map(({ user_role_id, user_role_title }) => {
          const role = { user_role_id, user_role_title }
          if (user_role_id === this.default_user_role) {
            role.default_user_role = true
          } else {
            role.default_user_role = false
          }
          return role
        })
        this.userRolesDataLoading = false
      }).catch(error => {
        this.$message.error(error)
      }).finally(() => {
        this.userRolesDataLoading = false
      })
    },

    editItem(item) {
      this.editedIndex = this.userRolesData.indexOf(item)
      this.editedItem = Object.assign({}, item)
      this.dialog = true
    },

    deleteItem(item) {
      this.editedIndex = this.userRolesData.indexOf(item)
      this.editedItem = Object.assign({}, item)
      this.dialogDelete = true
    },

    deleteItemConfirm() {
      const userRolesData = deepClone(this.userRolesData)
      userRolesData.splice(this.editedIndex, 1)
      this.deleteLoading = true
      setOptions({ user_roles: this.restoreUserRoleDataStructure(userRolesData) }).then(() => {
        this.userRolesData.splice(this.editedIndex, 1)
        this.closeDelete()
        this.deleteLoading = false
      }).catch(error => {
        this.$message.error(error)
      }).finally(() => {
        this.deleteLoading = false
      })
    },

    setDefaultUserRole(item) {
      if (Object.prototype.hasOwnProperty.call(item, 'defaultUserRoleLoading')) {
        item.defaultUserRoleLoading = true
      } else {
        this.$set(item, 'defaultUserRoleLoading', true)
      }
      setOptions({ default_user_role: item.user_role_id }).then(() => {
        this.userRolesData.forEach((row, index, array) => {
          if (row.user_role_id !== item.user_role_id && row.default_user_role === true) {
            array[index].default_user_role = false
          }
        })
        item.defaultUserRoleLoading = false
      }).catch(error => {
        this.$message.error(error)
        item.default_user_role = !item.default_user_role
      }).finally(() => {
        item.defaultUserRoleLoading = false
      })
    },

    createNewRoleId() {
      return new Date().getTime()
    },

    close() {
      this.dialog = false
      this.$nextTick(() => {
        this.editedItem = Object.assign({}, this.defaultItem)
        this.editedItem.user_role_id = this.createNewRoleId()
        this.editedIndex = -1
      })
    },

    closeDelete() {
      this.dialogDelete = false
      this.$nextTick(() => {
        this.editedItem = Object.assign({}, this.defaultItem)
        this.editedItem.user_role_id = this.createNewRoleId()
        this.editedIndex = -1
      })
    },

    save() {
      this.saveLoading = true
      const userRolesData = deepClone(this.userRolesData)
      if (this.editedIndex > -1) {
        Object.assign(userRolesData[this.editedIndex], this.editedItem)
      } else {
        userRolesData.push(this.editedItem)
      }
      setOptions({ user_roles: this.restoreUserRoleDataStructure(userRolesData) }).then(() => {
        if (this.editedIndex > -1) {
          Object.assign(this.userRolesData[this.editedIndex], this.editedItem)
        } else {
          this.userRolesData.push(this.editedItem)
        }
      }).catch(error => {
        this.$message.error(error)
      }).finally(() => {
        this.close()
        this.saveLoading = false
      })
    },

    restoreUserRoleDataStructure(userRoleData) {
      return userRoleData.map(({ user_role_id, user_role_title }) => {
        return { user_role_id, user_role_title }
      })
    }
  }
}
</script>
